import {
  Controller,
  Post,
  Get,
  Body,
  Res,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiProduces,
  ApiBody,
  ApiResponse
} from '@nestjs/swagger';
import { CozeService, ChatMessage } from '../services/coze.service';
import { Roles, CurrentUser } from '@app/auth';
import { Response as ExResponse } from 'express';

// Swagger DTOs
class TranslateRequestDto { text: string; lang?: string }
class FrontMatterRequestDto { content: string }
class CozeMessageDto { id?: string; role: 'user' | 'assistant' | 'system'; type?: string; content: string }
class ChatRequestDto { botId: string; messages: CozeMessageDto[] }

@ApiTags('Coze 集成')
@ApiBearerAuth()
@Controller('admin/coze')
export class CozeController {
  constructor(private readonly cozeService: CozeService) { }

  @Get('health')
  @ApiOperation({ summary: '健康检查' })
  @Roles('admin')
  async health() {
    return this.cozeService.health();
  }


  @Post('translate')
  @ApiOperation({ summary: '翻译文本', description: '将输入文本翻译为目标语言（默认中文环境）。注意：本接口仅接受 { text, lang? } 结构。若需要会话级参数（title、botType、metadata等），请使用 /admin/coze/chat。' })
  @ApiBody({
    schema: {
      type: 'object',
      required: ['text'],
      properties: {
        text: { type: 'string', description: '待翻译文本' },
        lang: { type: 'string', description: '目标语言（如 en/zh/ja 等）', example: 'en' },
      },
    },
    examples: {
      simple: {
        summary: '最小示例',
        value: { text: '你好世界', lang: 'en' },
      },
    },
  })
  @ApiResponse({
    status: 200,
    description: '翻译结果',
    schema: {
      type: 'object',
      properties: {
        status: { type: 'string', example: 'completed' },
        usage: {
          type: 'object',
          properties: {
            prompt_tokens: { type: 'number', example: 12 },
            completion_tokens: { type: 'number', example: 24 },
            total_tokens: { type: 'number', example: 36 },
          },
        },
        answer: { type: 'string', example: 'Hello, world' },
        messages: {
          type: 'array',
          items: {
            type: 'object',
            properties: {
              id: { type: 'string' },
              role: { type: 'string', enum: ['user', 'assistant', 'system'] },
              type: { type: 'string', description: '消息类型（text/image/file/object_string/function_call/tool_output）' },
              content: { type: 'string' },
              status: { type: 'string', enum: ['pending', 'completed', 'failed'] },
              meta_data: { type: 'object', nullable: true },
              usage: { type: 'object', nullable: true },
            },
          },
        },
      },
    },
  })
  @Roles('admin', 'editor')
  async translate(@Body() body: { text: string; lang?: string }, @CurrentUser('sub') userId?: number) {
    return this.cozeService.translate(body.text, body.lang, userId);
  }

  @Post('front-matter')
  @ApiOperation({ summary: '抽取 FrontMatter', description: '从正文中抽取 FrontMatter 元数据，返回 raw 字符串与 parsed JSON。' })
  @ApiBody({
    schema: {
      type: 'object',
      required: ['content'],
      properties: {
        content: { type: 'string', description: '文章正文内容' },
      },
    },
    examples: {
      basic: {
        value: { content: '# 标题\n\n内容正文...' },
      },
    },
  })
  @ApiResponse({
    status: 200,
    description: '提取结果',
    schema: {
      type: 'object',
      properties: {
        status: { type: 'string', example: 'completed' },
        usage: { type: 'object' },
        raw: { type: 'string', description: 'AI 原始返回字符串（应为 JSON 文本）' },
        parsed: { type: 'object', nullable: true, description: '解析后的 JSON 对象' },
        messages: { type: 'array', items: { type: 'object' } },
      },
    },
  })
  @Roles('admin', 'editor')
  async frontMatter(@Body() body: { content: string }, @CurrentUser('sub') userId?: number) {
    return this.cozeService.frontMatter(body.content, userId);
  }

  @Post('chat')
  @ApiOperation({ summary: '通用聊天（一次性返回）', description: '用于自定义 botId 与消息列表的对话。可代替 /translate 进行更丰富会话（支持附加 metadata 等扩展在服务内部使用）。' })
  @ApiBody({
    schema: {
      type: 'object',
      required: ['botId', 'messages'],
      properties: {
        botId: { type: 'string' },
        messages: {
          type: 'array',
          items: {
            type: 'object',
            required: ['role', 'content'],
            properties: {
              role: { type: 'string', enum: ['user', 'assistant', 'system'] },
              content: { type: 'string' },
              type: { type: 'string', description: '可选，消息类型' },
            },
          },
        },
      },
    },
    examples: {
      fromTranslate: {
        summary: '等价 translate 使用（推荐）',
        value: { botId: '你的翻译BOT_ID', messages: [{ role: 'user', content: '你好你好' }] },
      },
      rich: {
        summary: '更丰富的自定义',
        value: {
          botId: '你的BOT_ID',
          messages: [
            { role: 'system', content: '你是一个翻译助手' },
            { role: 'user', content: '你好你好' },
          ],
        },
      },
    },
  })
  @ApiResponse({ status: 200, description: 'Chat 完整响应（与 Coze SDK 返回结构一致）', schema: { type: 'object' } })
  @Roles('admin', 'editor')
  async chat(@Body() body: { botId: string; messages: ChatMessage[] }, @CurrentUser('sub') userId?: number) {
    return this.cozeService.chat(body.botId, body.messages, userId);
  }

  @Post('chat/stream')
  @ApiOperation({ summary: '通用聊天（SSE流）', description: '以 text/event-stream 逐步返回事件。事件可能包含：CONVERSATION_MESSAGE_DELTA、CONVERSATION_MESSAGE_COMPLETED 等。' })
  @ApiProduces('text/event-stream')
  @ApiBody({
    schema: {
      type: 'object',
      required: ['botId', 'messages'],
      properties: {
        botId: { type: 'string' },
        messages: {
          type: 'array',
          items: { type: 'object', required: ['role', 'content'], properties: { role: { type: 'string' }, content: { type: 'string' } } },
        },
      },
    },
    examples: {
      basic: { value: { botId: '你的BOT_ID', messages: [{ role: 'user', content: '你好' }] } },
    },
  })
  @ApiResponse({ status: 200, description: 'SSE 格式，例如：\n\n event: CONVERSATION_MESSAGE_DELTA\n data: {"content":"Hello"}\n' })
  @Roles('admin', 'editor')
  async stream(
    @Body() body: { botId: string; messages: ChatMessage[] },
    @Res() res: ExResponse,
    @CurrentUser('sub') userId?: number,
  ) {
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    const stream = await this.cozeService.stream(body.botId, body.messages);
    // TODO: 如需将流式增量也持久化，可在此累计 buffer 并在完成事件时调用保存

    try {
      for await (const part of stream as any) {
        if (part?.event && part?.data) {
          res.write(`event: ${part.event}\n`);
          res.write(`data: ${JSON.stringify(part.data)}\n\n`);
        } else {
          res.write(`data: ${JSON.stringify(part)}\n\n`);
        }
      }
    } catch (err) {
      res.write(`event: error\n`);
      res.write(`data: ${JSON.stringify({ message: String(err) })}\n\n`);
    } finally {
      res.end();
    }
  }
}
